﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;

namespace CorporationWars
{
    public delegate void UIEvent(UIZone sender);
    public delegate void NodeEvent(BaseNode sender);

    [Serializable]
    public class UIZone
    {
        protected SpriteBatch spriteBatch { get { return (SpriteBatch)Game.Services.GetService(typeof(SpriteBatch)); } }

        public object Tag { get; set; }
        public string Name { get; set; }
        public virtual Vector2 Position { get; set; }
        public virtual Vector2 OffSet { get; set; }

        public string TextureAsset { get; set; }
        public Color Color { get; set; }

        public int Width { get; set; }
        public int Height { get; set; }

        public bool IsMouseOver { get; set; }
        public bool IsMouseDown { get; set; }

        public bool IsVisible { get; set; }

        [NonSerialized]
        public UIEvent OnClick = null;
        [NonSerialized]
        public UIEvent OnClickHeld = null;

        public string ToolTipText { get; set; }
        public bool RenderToolTipTop { get; set; }

        /// <summary>
        /// 1 = must be solid
        /// </summary>
        public float OpacityTolerance = 1;

        [NonSerialized]
        public Game1 Game;
        
        public virtual Rectangle renderRectangle
        {
            get
            {
                return new Rectangle((int)(Position.X + OffSet.X), (int)(Position.Y + OffSet.Y), Width, Height);
            }
        }
        public Rectangle boundsRectangle
        {
            get
            {
                return new Rectangle((int)(Position.X + OffSet.X), (int)(Position.Y + OffSet.Y), Width, Height);
            }
        }

        public UIZone(Game1 game)
        {
            Game = game;

            IsVisible = true;
            ToolTipText = string.Empty;
            RenderToolTipTop = true;
        }

        [NonSerialized]
        Color[] colArray = null;
            

        protected Color[]  GetTextureMap(string textureAsset)
        {
            Color[] colData = new Color[Game.Content.Load<Texture2D>(textureAsset).Width * Game.Content.Load<Texture2D>(textureAsset).Height];
            Game.Content.Load<Texture2D>(textureAsset).GetData<Color>(colData);

            return colData;
        }
        public virtual void Update(GameTime gameTime)
        {
            if (!IsVisible)
                return;

            bool chk = false;

            if (Game.IsMouseOverRectangle(boundsRectangle))
            {
                if (TextureAsset != null)
                {
                    if (colArray == null)
                        colArray = GetTextureMap(TextureAsset);

                    if (Game.IsMouseOverSemiSolidPixel(Game.Content.Load<Texture2D>(TextureAsset), Position + OffSet, Width, Height, colArray, OpacityTolerance))
                        chk = true;
                }
                else
                    chk = true;

            }            

            if (chk)
            {
                IsMouseOver = true;
                Game.IsMouseOverUIZone = this;

                if (Game.LeftButtonDown)
                    IsMouseDown = true;
                else
                    IsMouseDown = false;

                if (Game.LeftButtonPressed && OnClick != null)
                    OnClick(this);
            }
            else
            {
                IsMouseOver = false;
                IsMouseDown = false;

                if (speechRepeat)
                    spokeTip = false;
            }

            if (IsMouseDown && OnClickHeld != null)
                OnClickHeld(this);

        }

        public virtual void Draw(GameTime gameTime)
        {
            spriteBatch.Draw(Game.Content.Load<Texture2D>(TextureAsset), renderRectangle, Color);
        }

        public bool spokeTip = false;
        public bool TipIsTutorial = true;
        public bool speechRepeat = false;

        public virtual void DrawToolTip(GameTime gameTime)
        {
            // Draw ToolTip
            if (!string.IsNullOrWhiteSpace(ToolTipText))
            {
                if (!spokeTip)
                {
                    spokeTip = true;
                    if (Game.AudioOn && Game.SpeechOn && (TipIsTutorial && Game.TutorialOn))
                        Game.Say(ToolTipText.Replace("/", " and "), true);
                    
                    else
                    {
                        if (!TipIsTutorial)
                            Game.Say(ToolTipText.Replace("/", " and "), true);
                    }
                }

                Vector2 padding = new Vector2(16, 8);
                Point mxy = new Point();
                if(RenderToolTipTop)
                    mxy = new Point(Game.ptrPos.X, Game.ptrPos.Y - Game.ptrSize);
                else
                    mxy = new Point(Game.ptrPos.X, Game.ptrPos.Y + Game.ptrSize);

                Vector2 xy = Game.Content.Load<SpriteFont>("Fonts/fontSmall").MeasureString(ToolTipText) + padding;

                // Need to keep it on the screen.
                if (mxy.X + xy.X > Game.GraphicsDevice.Viewport.Width)
                    mxy.X = Game.GraphicsDevice.Viewport.Width - (int)xy.X;

                if (RenderToolTipTop)
                {
                    if (mxy.Y - xy.Y < 0)
                        mxy.Y = 0;
                }
                else
                {
                    if (mxy.Y + xy.Y > Game.GraphicsDevice.Viewport.Height)
                        mxy.Y = (int)(Game.GraphicsDevice.Viewport.Height - xy.Y);
                }

                padding *= .5f;
                Point txy = new Point(mxy.X + (int)padding.X, mxy.Y + (int)padding.Y);
                spriteBatch.Draw(Game.Content.Load<Texture2D>("Textures/halfShade"), new Rectangle(mxy.X, mxy.Y, (int)xy.X, (int)xy.Y), Color.White);
                Game.RenderText(ToolTipText, new Vector2(txy.X, txy.Y), Color, -1, "Fonts/fontSmall");
            }
        }

        
    }
}
